#include <iostream>
#include <system_error>
#include "TaskQueue.h"
#include <mutex>
#include <stdlib.h>
#include <functional>

using std::cout;
using std::endl;
using std::unique_lock;
using ElemType = std::function<void()>;
TaskQueue::TaskQueue(size_t capa)
    :_capacity(capa)
    ,_que()
    ,_mutex()
     ,_notEmpty()
     ,_notFull()
,_flag(true){

     }
TaskQueue::~TaskQueue(){

}
void TaskQueue::push(ElemType &&ele){
    //加锁
    unique_lock<mutex> ul(_mutex);
    //判满
    while(full()){
        _notFull.wait(ul);
    }
    //放入数据
    _que.push(std::move(ele));
    //唤醒其他
    _notEmpty.notify_one();
}

ElemType TaskQueue::pop(){
    unique_lock<mutex> ul(_mutex);
    //判空
    while(empty() && _flag){
        _notEmpty.wait(ul);
    }
    if(_flag){
        //取出数据
        ElemType ele = _que.front();
        _que.pop();
        //唤醒其他
        _notFull.notify_one();
        return ele;
    }
    return nullptr;
}
bool TaskQueue::empty(){
    return 0==_que.size();
}
bool TaskQueue::full(){
    return _que.size() == _capacity;
}

void TaskQueue::wakeup(){
    //此二句顺序不能调换
    _flag = false;
    _notEmpty.notify_all();
}

